package com.cloud.rou.im.cluster.naming.node;

import com.cloud.rou.im.protocol.serialize.FastJsonSerializer;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.curator.framework.recipes.cache.TreeCacheListener;

import java.util.Optional;

/**
 * <p></p>
 *
 * @author GaoShuangWen
 */
@Slf4j
public class InstanceTreeCacheListener implements TreeCacheListener {

    private InstancePostProcessor processor;

    private InstanceParser<ChildData> parser = new DefaultByteToInstanceParser();

    public InstanceTreeCacheListener() {
        this.processor = new InstancePostProcessorAdapt();
    }

    public InstanceTreeCacheListener(InstancePostProcessor tInject) {
        this.processor = tInject;
    }

    @Override
    public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception {
        ChildData data = treeCacheEvent.getData();
        if (data != null) {
            Optional<ImServerInstance> parse = parser.parse(data);
            switch (treeCacheEvent.getType()) {
                case NODE_REMOVED:
                    parse.ifPresent(processor::instanceRemovedProcessor);
                break;
                case NODE_ADDED:
                    parse.ifPresent(processor::instanceAddedProcessor);
                    break;
                case NODE_UPDATED:
                    parse.ifPresent(processor::instanceUpdatedProcessor);
                    break;
                default:
                    break;
            }
        }else{
            log.debug("the class {} :data is null",this.getClass().getName());
        }
    }

    class DefaultByteToInstanceParser implements InstanceParser<ChildData> {
        @Override
        public Optional<ImServerInstance> parse(ChildData data) {
            byte[] payload = data.getData();
            if(payload!=null&&payload.length>0){
                return Optional.of(FastJsonSerializer.getInstance().deserialize(payload, ImServerInstance.class));
            }
            return Optional.empty();
        }
    }
}
